/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.merak.core.web.mvc;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

//@WebServlet(name="Main",urlPatterns={"/Main"})
@SuppressWarnings({"serial"})
public class FrontController extends HttpServlet {

    //~ Static ///////////////////////////////////////////////////////////////////
	//****************************************************************************
	private static String                   servletName = null;
	private static ThreadLocal<HttpSession> httpSession = new ThreadLocal<HttpSession>();

    //~ Attributes ///////////////////////////////////////////////////////////////
	//****************************************************************************
	private PageControllerMap controllers = null;
	private Dispatcher        dispatcher  = null;

    //~ Methods //////////////////////////////////////////////////////////////////
	//****************************************************************************
	@Override
	public void init() throws ServletException {

		// Initialize
		servletName      = this.getServletName();
		this.controllers = new PageControllerMap();
		this.dispatcher  = new Dispatcher(this.controllers);

	}
	//****************************************************************************
    /** Returns the servlet name. */
	public static String getName() {
		return servletName;
	}
	//****************************************************************************
    /** Makes available to rest of the system the http session associated with the
     *  current thread when the application runs in the Web Application Mode and
     *  with the MVC framework. Otherwise, it will return nothing. */
	public static HttpSession getCurrentHttpSession() {
		return httpSession.get();
	}
	//****************************************************************************
    @Override
    /** Executes when Servlet is invoked, dispatching the request to the correct
     *  business object and correct view. This is the core controller of the MVC
     *  action based architecture. */
    protected void service(HttpServletRequest request, HttpServletResponse response)
    		throws ServletException, IOException
    {
    	// Check if business name has been provided
    	String business = request.getParameter(MVCManager.getBusinessParameter());
    	if (business == null) throw new ServletException(
	   			"Business Name not specified. Try " +
	   			request.getRequestURL() + "?" +
	   			MVCManager.getBusinessParameter() + "=MyBusinessName"
   		);

    	// Attaches the current HttpSession to the current thread
    	httpSession.set(request.getSession());

    	// Execute...
    	try {
        	// Retrieve the controller responsible by handling the business
        	PageController controller = this.controllers.getController(business);
        	/* Execute the Business Logic, checking Authorization,
        	 * Session Expiration and redirecting to the view */
    		String view = controller.runBusinessLogic(request, response);
    		this.dispatcher.dispatchToView(view, request, response);
    	}
    	catch (SecurityException e) {
    		this.dispatcher.dispatchBadAccess(request, response);
    	}
    	catch (ServletException e) {
    		this.dispatcher.dispatchExecutionError(e, request, response);
    	}
	    catch (ExceptionView e) {
	    	this.dispatcher.dispatchToView(e, request, response);
		}

    }
    //****************************************************************************


}
